Skip to content

Apply the tagged union strategy to subsets of the configured union - #829

Closed
Aschenbath wants to merge 1 commit into
python-attrs:mainfrom
Aschenbath:fix/348-tagged-union-subsets
Closed

Aschenbath wants to merge 1 commit into
python-attrs:mainfrom
Aschenbath:fix/348-tagged-union-subsets

Conversation

@Aschenbath

Copy link
Copy Markdown

Summary

Fixes #348.

configure_tagged_union only registered hooks for the exact union it was given. A field typed with a subset of that union (for example A | B when A | B | C was configured) fell back to the default disambiguation, which fails for members it cannot tell apart:

configure_tagged_union(A | B | C, converter=conv)

@define
class Bar:
    y: A | B

conv.structure({"y": {"x": 1, "_type": "A"}}, Bar)
# TypeError: Could not disambiguate between A, B: no unique non-default attributes

The strategy now also registers structure and unstructure hook factories that claim any other union whose members are a subset of the configured union's members. The tag alone decides the member, and every member of a subset is already in the tag map, so the same hooks are reused. An additional None member is allowed, so optional subsets (A | B | None) work too; at least two real members are required, so a plain Optional[member] field is not claimed. A subset that is configured or registered separately keeps its own direct hooks, which take precedence over these factories.

Verification

  • The example from the issue now structures and unstructures through the tag, including a round trip and an A | B | None field.
  • New test test_subset_union in tests/strategies/test_tagged_unions.py.
  • tests/strategies/, tests/test_unions.py and tests/test_disambiguators.py: 327 passed, 15 xfailed.
  • ruff check and ruff format clean on the touched files.

@Aschenbath

Copy link
Copy Markdown
Author

Closing this one myself: I opened too many PRs here in a short time, which isn't fair to your review queue — sorry about that. I'm leaving #827 and #822 open. If this fix is something you'd want, I'm happy to reopen or rebase it later.

@Aschenbath Aschenbath closed this Nov 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support subset of tagged union strategy

1 participant